Skip to content

Feat/respect keyboard layout in code fallback#53

Merged
KevinVandy merged 4 commits intoTanStack:mainfrom
dmontagu:feat/respect-keyboard-layout-in-code-fallback
Mar 7, 2026
Merged

Feat/respect keyboard layout in code fallback#53
KevinVandy merged 4 commits intoTanStack:mainfrom
dmontagu:feat/respect-keyboard-layout-in-code-fallback

Conversation

@dmontagu
Copy link
Contributor

@dmontagu dmontagu commented Mar 7, 2026

🎯 Changes

Fixes #17

The matchesKeyboardEvent function falls back to event.code (physical key position) when event.key doesn't match the registered hotkey. This fallback exists to handle cases where modifier keys cause the OS to report a special character instead of the expected letter (e.g., macOS Option+T producing instead of T).

However, the fallback currently activates even when event.key is a standard ASCII letter — which means it matches based on physical key position rather than the keyboard layout's logical mapping. This breaks all non-QWERTY keyboard layouts (Dvorak, Colemak, AZERTY, etc.):

Example on Dvorak (macOS with "Use keyboard layout for shortcuts" enabled):

  1. User presses Cmd + physical B key → OS reports event.key='x', event.code='KeyB'
  2. A hotkey registered as Mod+B checks: 'x' === 'b'? No.
  3. Fallback kicks in: event.code = 'KeyB''B' === 'B'? Yes → hotkey fires incorrectly
  4. The user's Cmd+X (cut) is hijacked by the sidebar toggle bound to Mod+B

The fix: When event.key is already a standard ASCII letter (a-z), trust the keyboard layout and return false immediately. The event.code fallback is still used when event.key produces a non-letter character (e.g., , ´, dead keys).

(To be clear, this "example" was a real issue in our Pydantic Logfire app, and is precisely how I noticed this bug, as I am a Dvorak user myself. I have applied the diff from this PR in our own frontend build via pnpm patches, and the problem is now fixed for me.)

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

dmontagu added 2 commits March 6, 2026 16:57
…youts

The `matchesKeyboardEvent` function falls back to `event.code` (physical
key position) when `event.key` doesn't match the hotkey. This fallback
exists to handle cases like macOS Option+T producing '†' instead of 'T'.

However, when `event.key` is already a standard ASCII letter, this
fallback incorrectly matches based on physical key position, breaking
all non-QWERTY keyboard layouts (Dvorak, Colemak, AZERTY, etc.).

For example, on Dvorak with macOS "Use keyboard layout for shortcuts":
- Pressing Cmd + physical B key produces event.key='x', event.code='KeyB'
- A hotkey registered as 'Mod+B' would incorrectly match via the code
  fallback, even though the user pressed Cmd+X in their layout

The fix: when event.key is a standard ASCII letter (a-z), trust the
keyboard layout mapping and skip the event.code fallback. The fallback
is still used when event.key is a non-letter character (like '†') or
a dead key.

Fixes TanStack#17
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

Open in StackBlitz

@tanstack/hotkeys

npm i https://pkg.pr.new/@tanstack/hotkeys@53

@tanstack/hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/hotkeys-devtools@53

@tanstack/preact-hotkeys

npm i https://pkg.pr.new/@tanstack/preact-hotkeys@53

@tanstack/preact-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/preact-hotkeys-devtools@53

@tanstack/react-hotkeys

npm i https://pkg.pr.new/@tanstack/react-hotkeys@53

@tanstack/react-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/react-hotkeys-devtools@53

@tanstack/solid-hotkeys

npm i https://pkg.pr.new/@tanstack/solid-hotkeys@53

@tanstack/solid-hotkeys-devtools

npm i https://pkg.pr.new/@tanstack/solid-hotkeys-devtools@53

commit: b81eb21

@KevinVandy KevinVandy force-pushed the feat/respect-keyboard-layout-in-code-fallback branch from df20bf1 to 467f93c Compare March 7, 2026 22:09
@KevinVandy
Copy link
Member

@dmontagu I think I was able to solve non-ascii too by using regex /^\p{Letter}$/. Your tests still pass.

@KevinVandy KevinVandy merged commit 029f473 into TanStack:main Mar 7, 2026
3 checks passed
@github-actions github-actions bot mentioned this pull request Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hotkey registering both for the key and code fields for normal characters

2 participants